package com.blog.cmrpersonalblog.service;

import com.blog.cmrpersonalblog.dto.ranking.requset.RankingRequest;
import com.blog.cmrpersonalblog.dto.ranking.respnose.RankingResponse;
import com.blog.cmrpersonalblog.enums.RankingDimension;
import com.blog.cmrpersonalblog.enums.RankingType;

import java.time.LocalDateTime;

/**
 * 排行榜服务接口（重构版）
 * 支持文章榜、作者榜、收藏榜
 * 支持综合榜和分类榜
 * 基于Redis ZSet实现高性能排行榜功能
 */
public interface RankingService {

    /**
     * 获取榜单数据
     *
     * @param request 榜单查询请求
     * @return 榜单响应
     */
    RankingResponse getRanking(RankingRequest request);

    /**
     * 刷新所有榜单
     * 从数据库重新计算热度并更新到Redis
     */
    void refreshAllRankings();

    /**
     * 刷新指定类型和维度的榜单
     *
     * @param rankingType 榜单类型
     * @param dimension 榜单维度
     * @param categoryId 分类ID（分类榜时必填）
     */
    void refreshRanking(RankingType rankingType, RankingDimension dimension, Long categoryId);

    /**
     * 更新单个目标的榜单数据
     *
     * @param rankingType 榜单类型
     * @param targetId 目标ID（文章ID或作者ID）
     */
    void updateRankingItem(RankingType rankingType, Long targetId);

    /**
     * 从榜单中移除目标
     *
     * @param rankingType 榜单类型
     * @param targetId 目标ID
     */
    void removeFromRanking(RankingType rankingType, Long targetId);

    /**
     * 获取目标在榜单中的排名
     *
     * @param rankingType 榜单类型
     * @param dimension 榜单维度
     * @param categoryId 分类ID（分类榜时必填）
     * @param targetId 目标ID
     * @return 排名（从1开始，如果不在榜单中返回-1）
     */
    Long getRank(RankingType rankingType, RankingDimension dimension, Long categoryId, Long targetId);

    /**
     * 清空所有榜单
     */
    void clearAllRankings();

    /**
     * 获取榜单统计信息
     *
     * @return 统计信息
     */
    RankingStatistics getStatistics();

    /**
     * 获取下次更新时间
     *
     * @return 下次更新时间
     */
    LocalDateTime getNextUpdateTime();

    /**
     * 榜单统计信息
     */
    class RankingStatistics {
        private Long articleRankingCount;
        private Long authorRankingCount;
        private Long collectionRankingCount;
        private Long totalRankingCount;
        private LocalDateTime lastUpdateTime;
        private LocalDateTime nextUpdateTime;

        // getters and setters
        public Long getArticleRankingCount() { return articleRankingCount; }
        public void setArticleRankingCount(Long articleRankingCount) { this.articleRankingCount = articleRankingCount; }

        public Long getAuthorRankingCount() { return authorRankingCount; }
        public void setAuthorRankingCount(Long authorRankingCount) { this.authorRankingCount = authorRankingCount; }

        public Long getCollectionRankingCount() { return collectionRankingCount; }
        public void setCollectionRankingCount(Long collectionRankingCount) { this.collectionRankingCount = collectionRankingCount; }

        public Long getTotalRankingCount() { return totalRankingCount; }
        public void setTotalRankingCount(Long totalRankingCount) { this.totalRankingCount = totalRankingCount; }

        public LocalDateTime getLastUpdateTime() { return lastUpdateTime; }
        public void setLastUpdateTime(LocalDateTime lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; }

        public LocalDateTime getNextUpdateTime() { return nextUpdateTime; }
        public void setNextUpdateTime(LocalDateTime nextUpdateTime) { this.nextUpdateTime = nextUpdateTime; }
    }
}
